using System;
using System.Collections;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.Runtime.CompilerServices;
using PickGold.Charting;

namespace PickGold.Charting.ChartTypes
{
	internal class FastLineChart : IChartType, IDisposable
	{
		internal bool chartArea3DEnabled;
		internal Matrix3D matrix3D;
		internal float seriesZCoordinate;

		public void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list)
		{
		}

		public void Dispose()
		{
			this.Dispose(true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
		}

		public virtual void DrawLine(Series series, DataPoint point, DataPoint pointMin, DataPoint pointMax, int pointIndex, Pen pen, float firstPointX, float firstPointY, float secondPointX, float secondPointY)
		{
			if (this.chartArea3DEnabled)
			{
				Point3D[] points = new Point3D[2];
				PointF relativePoint = this.Graph.GetRelativePoint(new PointF(firstPointX, firstPointY));
				PointF tf2 = this.Graph.GetRelativePoint(new PointF(secondPointX, secondPointY));
				points[0] = new Point3D(relativePoint.X, relativePoint.Y, this.seriesZCoordinate);
				points[1] = new Point3D(tf2.X, tf2.Y, this.seriesZCoordinate);
				this.matrix3D.TransformPoints(points);
				points[0].PointF = this.Graph.GetAbsolutePoint(points[0].PointF);
				points[1].PointF = this.Graph.GetAbsolutePoint(points[1].PointF);
				firstPointX = points[0].X;
				firstPointY = points[0].Y;
				secondPointX = points[1].X;
				secondPointY = points[1].Y;
			}
			this.Graph.DrawLine(pen, firstPointX, firstPointY, secondPointX, secondPointY);
			if (this.Common.ProcessModeRegions)
			{
				using (GraphicsPath path = new GraphicsPath())
				{
					float num = pen.Width + 2f;
					if (Math.Abs((float)(firstPointX - secondPointX)) > Math.Abs((float)(firstPointY - secondPointY)))
					{
						path.AddLine(firstPointX, firstPointY - num, secondPointX, secondPointY - num);
						path.AddLine(secondPointX, secondPointY + num, firstPointX, firstPointY + num);
						path.CloseAllFigures();
					}
					else
					{
						path.AddLine(firstPointX - num, firstPointY, secondPointX - num, secondPointY);
						path.AddLine(secondPointX + num, secondPointY, firstPointX + num, firstPointY);
						path.CloseAllFigures();
					}
					RectangleF bounds = path.GetBounds();
					if ((bounds.Width <= 2.0) || (bounds.Height <= 2.0))
					{
						bounds.Inflate(pen.Width, pen.Width);
						this.Common.HotRegionsList.AddHotRegion(this.Graph.GetRelativeRectangle(bounds), point, point.series.Name, pointIndex);
					}
					else
					{
						this.Common.HotRegionsList.AddHotRegion(path, false, this.Graph, point, point.series.Name, pointIndex);
					}
				}
			}
		}

		public virtual Image GetImage(ChartTypeRegistry registry)
		{
			return (Image)registry.ResourceManager.GetObject(this.Name + "ChartType");
		}

		public virtual LegendImageStyle GetLegendImageStyle(Series series)
		{
			return LegendImageStyle.Line;
		}

		public virtual double GetYValue(CommonElements common, ChartArea area, Series series, DataPoint point, int pointIndex, int yValueIndex)
		{
			return point.YValues[yValueIndex];
		}

		public virtual void Paint(ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw)
		{
			this.Common = common;
			this.Graph = graph;
			bool flag = false;
			if (area.Area3DStyle.Enable3D)
			{
				this.chartArea3DEnabled = true;
				this.matrix3D = area.matrix3D;
			}
			else
			{
				this.chartArea3DEnabled = false;
			}
			foreach (Series series in common.DataManager.Series)
			{
				if (((string.Compare(series.ChartTypeName, this.Name, true, CultureInfo.CurrentCulture) != 0) || (series.ChartArea != area.Name)) || !series.IsVisible())
				{
					continue;
				}
				if (this.chartArea3DEnabled)
				{
					float num;
					area.GetSeriesZPositionAndDepth(series, out num, out this.seriesZCoordinate);
					this.seriesZCoordinate += num / 2f;
				}
				Axis axis = area.GetAxis(AxisName.X, series.XAxisType, area.Area3DStyle.Enable3D ? string.Empty : series.XSubAxisName);
				Axis axis2 = area.GetAxis(AxisName.Y, series.YAxisType, area.Area3DStyle.Enable3D ? string.Empty : series.YSubAxisName);
				double viewMinimum = axis.ViewMinimum;
				double viewMaximum = axis.ViewMaximum;
				double num4 = axis2.ViewMinimum;
				double num5 = axis2.ViewMaximum;
				float width = 1f;
				if (series.IsCustomPropertySet("PermittedPixelError"))
				{
					float num7;
					string s = series["PermittedPixelError"];
					if (!float.TryParse(s, NumberStyles.Any, CultureInfo.CurrentCulture, out num7))
					{
						throw new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid2("PermittedPixelError"));
					}
					width = num7;
					if ((width < 0f) || (width > 1f))
					{
						throw new InvalidOperationException(SR.ExceptionCustomAttributeIsNotInRange0to1("PermittedPixelError"));
					}
				}
				SizeF relativeSize = graph.GetRelativeSize(new SizeF(width, width));
				SizeF ef2 = graph.GetRelativeSize(new SizeF((float)viewMinimum, (float)num4));
				double num8 = Math.Abs((double)(axis.PositionToValue((double)(ef2.Width + relativeSize.Width), false) - axis.PositionToValue((double)ef2.Width, false)));
				Pen pen = new Pen(series.Color, (float)series.BorderWidth);
				pen.DashStyle = graph.GetPenStyle(series.BorderDashStyle);
				pen.StartCap = LineCap.Round;
				pen.EndCap = LineCap.Round;
				Pen pen2 = new Pen(series.EmptyPointStyle.Color, (float)series.EmptyPointStyle.BorderWidth);
				pen2.DashStyle = graph.GetPenStyle(series.EmptyPointStyle.BorderDashStyle);
				pen2.StartCap = LineCap.Round;
				pen2.EndCap = LineCap.Round;
				bool flag3 = ChartHelper.IndexedSeries(this.Common, new string[] { series.Name });
				int pointIndex = 0;
				double naN = double.NaN;
				double axisValue = double.NaN;
				DataPoint pointMin = null;
				DataPoint pointMax = null;
				double yValue = 0.0;
				double logValue = 0.0;
				double num14 = 0.0;
				double num15 = 0.0;
				DataPoint point = null;
				PointF empty = PointF.Empty;
				PointF tf2 = PointF.Empty;
				PointF tf3 = PointF.Empty;
				bool flag4 = false;
				bool flag5 = false;
				bool flag6 = false;
				bool isEmpty = false;
				bool flag8 = false;
				double num16 = (graph.Common.ChartPicture.Width - 1.0) / 100.0;
				double num17 = (graph.Common.ChartPicture.Height - 1.0) / 100.0;
				foreach (DataPoint point4 in series.Points)
				{
					yValue = flag3 ? ((double)(pointIndex + 1)) : point4.XValue;
					yValue = axis.GetLogValue(yValue);
					logValue = axis2.GetLogValue(point4.YValues[0]);
					isEmpty = point4.IsEmpty;
					if ((flag6 && !isEmpty) && !flag8)
					{
						flag8 = true;
						isEmpty = true;
					}
					else
					{
						flag8 = false;
					}
					if (!flag5 && ((((yValue < viewMinimum) && (num14 < viewMinimum)) || ((yValue > viewMaximum) && (num14 > viewMaximum))) || (((logValue < num4) && (num15 < num4)) || ((logValue > num5) && (num15 > num5)))))
					{
						num14 = yValue;
						num15 = logValue;
						flag4 = true;
						pointIndex++;
						continue;
					}
					if (!flag && ((((num14 < viewMinimum) || (num14 > viewMaximum)) || ((yValue > viewMaximum) || (yValue < viewMinimum))) || (((num15 < num4) || (num15 > num5)) || ((logValue < num4) || (logValue > num5)))))
					{
						graph.SetClip(area.PlotAreaPosition.ToRectangleF());
						flag = true;
					}
					if (((pointIndex > 0) && (isEmpty == flag6)) && (Math.Abs((double)(yValue - num14)) < num8))
					{
						if (!flag5)
						{
							flag5 = true;
							if (logValue > num15)
							{
								axisValue = logValue;
								naN = num15;
								pointMax = point4;
								pointMin = point;
							}
							else
							{
								axisValue = num15;
								naN = logValue;
								pointMax = point;
								pointMin = point4;
							}
						}
						else if (logValue > axisValue)
						{
							axisValue = logValue;
							pointMax = point4;
						}
						else if (logValue < naN)
						{
							naN = logValue;
							pointMin = point4;
						}
						point = point4;
						empty.Y = (float)logValue;
						pointIndex++;
						continue;
					}
					tf3.X = (float)(axis.GetLinearPosition(yValue) * num16);
					tf3.Y = (float)(axis2.GetLinearPosition(logValue) * num17);
					if (flag4)
					{
						tf2.X = (float)(axis.GetLinearPosition(num14) * num16);
						tf2.Y = (float)(axis2.GetLinearPosition(num15) * num17);
					}
					if (flag5)
					{
						naN = axis2.GetLinearPosition(naN) * num17;
						axisValue = axis2.GetLinearPosition(axisValue) * num17;
						this.DrawLine(series, point, pointMin, pointMax, pointIndex, flag6 ? pen2 : pen, tf2.X, (float)naN, tf2.X, (float)axisValue);
						flag5 = false;
						tf2.Y = (float)(axis2.GetLinearPosition((double)empty.Y) * num17);
					}
					if (pointIndex > 0)
					{
						this.DrawLine(series, point4, pointMin, pointMax, pointIndex, isEmpty ? pen2 : pen, tf2.X, tf2.Y, tf3.X, tf3.Y);
					}
					num14 = yValue;
					num15 = logValue;
					point = point4;
					tf2 = tf3;
					flag4 = false;
					flag6 = isEmpty;
					pointIndex++;
				}
				if (flag5)
				{
					if (flag4)
					{
						tf2.X = (float)(axis.GetLinearPosition(num14) * num16);
						tf2.Y = (float)(axis2.GetLinearPosition(num15) * num17);
					}
					naN = axis2.GetLinearPosition(naN) * num17;
					axisValue = axis2.GetLinearPosition(axisValue) * num17;
					this.DrawLine(series, point, pointMin, pointMax, pointIndex - 1, flag6 ? pen2 : pen, tf2.X, (float)naN, tf2.X, (float)axisValue);
					flag5 = false;
					naN = double.NaN;
					axisValue = double.NaN;
					pointMin = null;
					pointMax = null;
				}
			}
			if (flag)
			{
				graph.ResetClip();
			}
		}

		public virtual bool ApplyPaletteColorsToPoints
		{
			get
			{
				return false;
			}
		}

		public bool CircularChartArea
		{
			get
			{
				return false;
			}
		}

		internal CommonElements Common { set; get; }

		public virtual bool DataPointsInLegend
		{
			get
			{
				return false;
			}
		}

		public virtual bool ExtraYValuesConnectedToYAxis
		{
			get
			{
				return false;
			}
		}

		internal ChartGraphics Graph { set; get; }

		public virtual bool HundredPercent
		{
			get
			{
				return false;
			}
		}

		public virtual bool HundredPercentSupportNegative
		{
			get
			{
				return false;
			}
		}

		public virtual string Name
		{
			get
			{
				return "FastLine";
			}
		}

		public virtual bool RequireAxes
		{
			get
			{
				return true;
			}
		}

		public virtual bool SecondYScale
		{
			get
			{
				return false;
			}
		}

		public virtual bool SideBySideSeries
		{
			get
			{
				return false;
			}
		}

		public virtual bool Stacked
		{
			get
			{
				return false;
			}
		}

		public bool StackSign
		{
			get
			{
				return false;
			}
		}

		public virtual bool SupportLogarithmicAxes
		{
			get
			{
				return true;
			}
		}

		public virtual bool SupportStackedGroups
		{
			get
			{
				return false;
			}
		}

		public virtual bool SwitchValueAxes
		{
			get
			{
				return false;
			}
		}

		public virtual int YValuesPerPoint
		{
			get
			{
				return 1;
			}
		}

		public virtual bool ZeroCrossing
		{
			get
			{
				return false;
			}
		}
	}
}

